#ifndef __LEOS_LIST_H__
#define __LEOS_LIST_H__

#define le_list_inline  static __inline

struct le_list_node {
    struct le_list_node *prev;
    struct le_list_node *next;
};

typedef struct le_list_node le_list_t;

le_list_inline void le_list_init(le_list_t *list)
{
    list->next = list;
    list->prev = list;
}

le_list_inline void le_list_insert_before(le_list_t *new, le_list_t *pos)
{
    new->next = pos;
    new->prev = pos->prev;

    pos->prev->next = new;
    pos->prev = new;
}

le_list_inline void le_list_insert_after(le_list_t *new, le_list_t *pos)
{
    new->next = pos->next;
    new->prev = pos;

    pos->next->prev = new;
    pos->next = new;
}

le_list_inline void le_list_remove(le_list_t *list)
{
    list->prev->next = list->next;
    list->next->prev = list->prev;

    list->next = list->prev = list;
}

le_list_inline int le_list_isempty(le_list_t *list)
{
    return (list->next == list);
}

le_list_inline int le_list_len(le_list_t *list)
{
    unsigned long len = 0;
    le_list_t *p = list;

    while (p->next != list) {
        len++;
        p = p->next;
    }

    return len;
}

#define LE_LIST_HEAD_INIT(head) le_list_t head = {&head, &head}

#define le_list_for_each(node, head) \
            for (le_list_t *node = (head)->next; node != (head); node = node->next)

#define le_list_for_each_safe(node, head) \
            for (le_list_t *node = (head)->next, *n = node->next; \
                node != (head); node = n, n = node->next)

#endif

